package cn.gailvlun.gll.presentation.hotel.day

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.databinding.DataBindingUtil
import android.os.Bundle
import android.os.Environment
import android.view.View
import cn.gailvlun.gll.R
import cn.gailvlun.gll.config.Constants
import cn.gailvlun.gll.databinding.ActivityHotelSpeakBinding
import cn.gailvlun.gll.net.HotelTemplate
import cn.gailvlun.gll.presentation.base.BaseActivity
import cn.gailvlun.gll.presentation.hotel.event.PermissionEvent
import cn.gailvlun.gll.util.AudioUtil
import cn.gailvlun.gll.util.OnPlayerTimerListener
import cn.gailvlun.gll.util.PlayerTimer
import cn.gailvlun.gll.util.ToastUtil
import cn.gailvlun.gll.widget.*
import com.afollestad.materialdialogs.MaterialDialog
import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.ToastUtils
import com.tbruyelle.rxpermissions2.RxPermissions
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.File
import java.text.MessageFormat
import java.util.*


class HotelSpeakActivity : BaseActivity() {

    companion object {
        fun openActivity(context: Context) {
            val intent = Intent(context, HotelSpeakActivity::class.java)
            context.startActivity(intent)
        }
    }

    private lateinit var mBinding: ActivityHotelSpeakBinding
    private var audioRecordDemo: AudioRecordDemo? = null
    var path = File(Environment.getExternalStorageDirectory(), "gailvlun/audio/")
    private val defaultFileName = UUID.randomUUID().toString()
    private lateinit var file: File
    private val playerTimer = PlayerTimer()

    override fun initComponent() {
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_hotel_speak)
        mBinding.presenter = Presenter()
    }

    override fun createHandler() {
        mBinding.nbv.setOnBackListener { onBackPressed() }

        RxPermissions(mContext)
                .request(Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe { aBoolean ->
                    mBinding.recordView.isHasPermission = aBoolean
                }

        playerTimer.mOnPlayerTimerListener = object : OnPlayerTimerListener {
            override fun onTick(duration: Long) {
                runOnUiThread {
                    setProgressText(duration)
                }
            }

            override fun onFinish(mDuration: Long) {
                runOnUiThread {
                    setProgressText(mDuration)
                    mBinding.recordView.setState(RUN_OUT_OF_TIME)
                }
            }
        }

        mBinding.recordView.onStateChangeListener = object : OnStateChangeListener {
            override fun onStateChange(state: Long) {
                when (state) {
                    START -> {
                        
                        FileUtils.deleteFile(file)
                        playerTimer.restart()
                        mBinding.isRecorded = false
                    }
                    RECORDING -> {
                        mBinding.isRecorded = true
                        if (FileUtils.createOrExistsDir(path)) {
                            audioRecordDemo = AudioRecordDemo()
                            audioRecordDemo?.startRecord(file.path)
                        }
                        mBinding.wlv.startAnim()
                        playerTimer.start(Constants.Record.recordTime)
                    }
                    PAUSING -> {
                        audioRecordDemo?.pauseRecord()
                        mBinding.wlv.stopAnim()
                        playerTimer.pause()
                    }
                    RETRY_RECORDING -> {
                        audioRecordDemo?.resumeRecord()
                        mBinding.wlv.startAnim()
                        playerTimer.resume()
                    }
                    DONE -> {
                        if (AudioUtil.getDuration(file.path) > 1000) {
                            audioRecordDemo?.stopRecord()
                            HotelWriteActivity.openActivity(mContext, audioRecordDemo?.getCurrentFile())
                        } else {
                            ToastUtil.showShort(getString(R.string.hotel_speak_record_short))
                        }
                    }
                    RUN_OUT_OF_TIME -> {
                        audioRecordDemo?.stopRecord()
                        mBinding.wlv.stopAnim()
                    }
                }
            }
        }
    }

    override fun loadData(savedInstanceState: Bundle?) {
        file = File(path, defaultFileName + ".aac")
    }

    override fun onResume() {
        super.onResume()
        mBinding.wlv.onResume()
    }

    override fun onPause() {
        super.onPause()
        mBinding.wlv.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        playerTimer.mOnPlayerTimerListener = null
    }

    override fun onBackPressed() {
        MaterialDialog.Builder(mContext)
                .title(getString(R.string.hotel_speak_dialog_title))
                .positiveText(getString(R.string.ok))
                .onPositive { dialog, which ->
                    FileUtils.deleteFile(file)
                    finish()
                }
                .negativeText(getString(R.string.cancel))
                .show()
    }

    private fun setProgressText(currentPosition: Long) {
        mBinding.tvTimer.text = "${getLongFromMill(currentPosition)}/${getLongFromMill(Constants.Record.recordTime)}"
    }

    private fun getLongFromMill(mill: Long?): String {
        return if (mill != null) {
            format(getString(R.string.hotel_speak_time_format), mill.div(1000 * 60), mill.div(1000) % 60)
        } else {
            getString(R.string.hotel_time_format_default)
        }
    }

    fun format(pattern: String, vararg arguments: Any): String {
        return MessageFormat.format(pattern, *arguments)
    }

    inner class Presenter {
        fun onSelectTemplate() {
            HotelTemplateActivity.openActivity(mContext)
                    .subscribe { rx_activity_result2 ->
                        if (rx_activity_result2.resultCode() == Activity.RESULT_OK) {
                            val template = rx_activity_result2.data().getSerializableExtra("template") as HotelTemplate
                            mBinding.template = template
                            mBinding.invalidateAll()
                        }
                    }
        }

        fun deleteCurrentTemplate() {
            mBinding.template = null
            mBinding.invalidateAll()
        }
    }

    object Util {
        @JvmStatic
        fun getTemplateName(template: HotelTemplate?): String? {
            return template?.title
        }

        @JvmStatic
        fun getTemplateContent(template: HotelTemplate?): String? {
            return template?.text
        }

        @JvmStatic
        fun getTemplateVisibility(template: HotelTemplate?): Int {
            return if (template == null) View.GONE else View.VISIBLE
        }

        @JvmStatic
        fun getAddTemplateVisibility(template: HotelTemplate?, isRecorded: Boolean): Int {
            return if (template == null)
                if (isRecorded) View.GONE else View.VISIBLE
            else View.GONE
        }

        @JvmStatic
        fun getEmptyTemplateVisibility(template: HotelTemplate?, isRecorded: Boolean): Int {
            return if (template == null)
                if (isRecorded) View.VISIBLE else View.GONE
            else View.GONE
        }

        @JvmStatic
        fun getDeleteTemplateVisibility(isRecorded: Boolean): Int {
            return if (isRecorded) View.GONE else View.VISIBLE
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun transferPermissionEvent(event:PermissionEvent) {
        if (!event.canAudio){
            ToastUtils.showShort("无录音权限,请授权")
            mBinding.wlv.stopAnim()
            mBinding.recordView.clear()
            FileUtils.deleteFile(file)

            mBinding.isRecorded = false

            audioRecordDemo?.stopRecord()


            playerTimer.clear()
            setProgressText(0)

        }
    }

}